<?php
/**
 * Created by paperphp
 * User: 22071
 * Date: 2019/6/25
 * Email: <zhendongdong@foxmail.com>
 */

namespace paper;


use paper\constraint\ExceptionsHandler;
use paper\constraint\Kernel as KernelConstraint;
use paper\exception\ExceptionsHandlerRegister;
use paper\http\Response;

class Kernel implements KernelConstraint
{

    private $runtime = [];
    private $app;

    public function __construct(App $app)
    {
        $this->app = $app;
    }

    /**
     * 开始运行
     * @return bool|Response
     * @throws Exception
     */
    public function handler()
    {
        $this->exceptionsHandlerRegister();
        //开始统计系统运行信息
        $this->proStartTime();
        //初始化
        $this->initialize();
        try {
            return $this->sendRequestThroughRouter();
        } catch (\Exception $exception) {
            return $this->renderExceptions($exception);
        } catch (\Throwable $exception) {
            return $this->renderExceptions($exception);
        }
    }

    private function exceptionsHandlerRegister()
    {
        $this->app->make(ExceptionsHandlerRegister::class)->register();
    }

    /**
     * @return Response
     * @throws Exception
     * @throws \ReflectionException
     */
    private function sendRequestThroughRouter()
    {
        //先初始化调度信息
        return $this->app->router->dispatch();
    }

    /**
     * @param $exception
     * @return mixed
     * @throws Exception
     */
    private function renderExceptions($exception)
    {
        /**@var ExceptionsHandler $exceptionHandler * */
        $exceptionHandler = $this->app->make(ExceptionsHandler::class);
        $exceptionHandler->report($exception);
        return $exceptionHandler->render($exception);
    }

    /**
     * 初始化
     */
    private function initialize()
    {

        //加载路由文件
        $route_file = ROOT . DIRECTORY_SEPARATOR . APP . DIRECTORY_SEPARATOR . 'route.php';
        if (is_file($route_file)) {
            require $route_file;
        }

        //加载应用公共文件
        $common_file = ROOT . DIRECTORY_SEPARATOR . APP . DIRECTORY_SEPARATOR . 'common.php';
        if (is_file($common_file)) {
            require $common_file;
        }


        //开启缓存
        ob_start();
        //设置时区
        date_default_timezone_set($this->app->config->app('default_timezone'));

        //启动session
        if ($this->app->config->session('session_auto_start')) {
            $this->app->session->start();
        }

    }

    /**
     * 开始统计信息
     */
    private function proStartTime()
    {
        $mtime1                    = explode(" ", microtime());
        $this->runtime['use_time'] = $mtime1[1] + $mtime1[0];
        $this->runtime['memory']   = memory_get_usage();
    }

    /**
     * 结束统计信息
     * @return array
     */
    public function proEndTime()
    {
        $this->runtime['memory']   = memory_get_usage() - $this->runtime['memory'];
        $mtime2                    = explode(" ", microtime());
        $this->runtime['use_time'] = $mtime2[1] + $mtime2[0] - $this->runtime['use_time'];
        return $this->runtime;
    }


    public function terminate()
    {

    }

    public function getApplication()
    {
        return $this->app;
    }
}